package com.rpp.utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.rpp.config.DruidConfig;
import com.rpp.config.ZookeeperConfig;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;

/**
 * @Description
 * @Author rpp
 * @Date 2020/8/11 12:30 上午
 */
public class DatasourceUtil {

    public static DruidDataSource dataSource;

    /**
     * 初始化连接池
     *
     * @return
     */
    public static void initDatasource(DruidConfig druidConfig, ZkClient zkClient) {

        //如果数据源配置节点不存，先创建节点
        boolean exists = zkClient.exists(ZookeeperConfig.DATASOURCE_NODE);
        if (!exists) {
            zkClient.createPersistent(ZookeeperConfig.DATASOURCE_NODE);
        }

        //读取数据源配置
        Object obj = zkClient.readData(ZookeeperConfig.DATASOURCE_NODE);
        //如果数据源配置为空，取默认配置
        if (null != obj) {
            druidConfig = JsonUtil.toObject(obj.toString(), DruidConfig.class);
        }
        System.out.println("初始化数据库连接池。。。");
        setDatasource(druidConfig);

        //注册数据源配置节点数据变更事件通知
        zkClient.subscribeDataChanges(ZookeeperConfig.DATASOURCE_NODE, new IZkDataListener() {

            /**
             * 节点数据变更事件通知
             *
             * @param dataPath
             * @param data
             * @throws Exception
             */
            @Override
            public void handleDataChange(String dataPath, Object data) throws Exception {
                System.out.println("数据源配置发生变化。。。");

                //读取数据源配置
                Object obj = zkClient.readData(ZookeeperConfig.DATASOURCE_NODE);
                try {
                    DruidConfig config = JsonUtil.toObject(obj.toString(), DruidConfig.class);

                    //关闭旧的数据源，重新设置新的
                    dataSource.close();
                    System.out.println("关闭数据连接池并重新创建新的连接池。。。");

                    setDatasource(config);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("数据源配置异常");
                }
            }

            /**
             * 节点数据被删除事件通知
             *
             * @param dataPath
             * @throws Exception
             */
            @Override
            public void handleDataDeleted(String dataPath) throws Exception {
                System.out.println("节点数据被删除。。。");
            }
        });

    }

    /**
     * 更改数据库连接池
     *
     * @param config
     */
    private static void setDatasource(DruidConfig config) {
        dataSource = new DruidDataSource();
        dataSource.setUrl(config.getUrl());
        //这个可以缺省的，会根据url自动识别
        dataSource.setDriverClassName(config.getDriverClassName());
        dataSource.setUsername(config.getUserName());
        dataSource.setPassword(config.getPassword());

        //下面都是可选的配置
        //初始连接数，默认0
        dataSource.setInitialSize(config.getInitialSize());
        //最大连接数，默认8
        dataSource.setMaxActive(config.getMaxActive());
        //最小闲置数
        dataSource.setMinIdle(config.getMinIdle());
        //获取连接的最大等待时间，单位毫秒
        dataSource.setMaxWait(config.getMaxWait());
    }

}
